from django.template import Context, Template, loader
from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout
from django.conf import settings
from xml.dom.minidom import Document
import os, os.path, datetime, zipfile, pickle
from main import models
from main import forms
from lib.serialization import sunit
from random import randint
#####################################################################################
#REST views
#####################################################################################
def rest_register(request):
    if request.method == 'POST':
        #registering node
        caption, uid, key = request.POST['caption'], request.POST['uid'], request.POST['key']
        cpu_power, cpu_number, platform = request.POST['cpu_power'], request.POST['cpu_number'], request.POST['platform']
        the_user = models.person.objects.get(id = uid)
        if the_user.key == key:
            the_node = models.node(caption=caption, person=the_user,key=generate_key(), cpu_power=cpu_power, cpu_number=cpu_number, platform=platform)
            the_node.save()
            #generating  xml
            doc = Document()
            root = doc.createElement("node")
            doc.appendChild(root)
            xml_text(doc,root,"id",the_node.id)
            xml_text(doc,root,"caption",the_node.get_caption())
            xml_text(doc,root,"key",the_node.key)
            xml_text(doc,root,"link",settings.NODE_LINK_INTERNAL)
            return HttpResponse(doc.toxml())
        else:
            HttpResponse.status_code=500
            return HttpResponse('bad key')
    return HttpResponse('None')

def rest_unit(request):
    if request.method == 'POST':
        #validate node
        node = get_node(request.POST['nid'], request.POST['key'])
        if not node:
            HttpResponse.status_code=500
            return HttpResponse('key error')
        #fetch upload
        if request.POST['upload']!=u'None':
            runit = pickle.loads(request.POST['upload'].encode('ascii'))
            push_unit(runit, node)
        #submit new task to node
        unit = pop_unit()
        if not unit:
            HttpResponse.status_code=404
            return HttpResponse('nothing to process')
        return HttpResponse(pickle.dumps(unit))

def rest_checkout_file(request, type, caption, version_client):
        path = type + '/' + caption + '/'
        fullpath = settings.ROOT + 'trunk/' + path
        version_client = float(version_client)
        try:
            version_server = open(fullpath+'version')
            version_server = float(version_server.read())
        except:
            version_server = 0
        if version_client >= version_server and version_server:
            response = HttpResponse('Not modified')
            response.status_code = 201
        else:
            file = 'module.zip'
            os.remove(fullpath+file)
            pyzip = zipfile.PyZipFile(fullpath+file,'w')
            try:
                pyzip.write(fullpath+'version','version')
            except:
                pass
            pyzip.writepy(fullpath)
            pyzip.close()
            f = open(fullpath+'module.zip','rb')
            data = f.read()
            f.close()
            response = HttpResponse(data, mimetype='application/x-zip-compressed')
            response['Content-Disposition'] = 'attachment; filename=module.zip'
            response.status_code = 200
        return response

#####################################################################################
#Secondary functions
#####################################################################################
def tpl(name, context=Context()):
    return HttpResponse(loader.get_template(name).render(context))

def itpl(name, context={}):
    return loader.get_template(name).render(Context(context))

def generate_key():
    import uuid
    return str(uuid.uuid4())+'-'+str(uuid.uuid4())

def stub():
    pass

def xml_text(doc,root,child,text):
    child = doc.createElement(child)
    child.appendChild(doc.createTextNode(str(text)))
    root.appendChild(child)

def get_node(nid,key):
    try:
        return models.node.objects.get(id=nid,key=key)
    except:
        return None

def pop_unit():
    #try:
        num_units = models.unit.objects.filter(status=-1).count()
        if num_units:
            unit = models.unit.objects.filter(status=-1)[randint(0, num_units-1)]
            r = sunit(unit)
            unit.save()
            return r
        return None
    #except:
    #    return None

def push_unit(runit, node):
    print 'pushing'
    unit = models.unit.objects.get(id=runit.id)
    #calculating flops
    dt = datetime.datetime.now() - unit.creation_date
    flops = dt.seconds * node.cpu_power
    print 'ok flops'
    node.cpu_flops += flops
    node.save()

    node.person.cpu_flops += flops
    node.person.save()
    print 'ok node + person'
    unit.ticket.spent_flops += flops
    unit.ticket.save()

    unit.ticket.person.spent_flops += flops
    unit.ticket.person.save()
    print 'ok ticket + person'

    #pushing unit

    unit.fitness = runit.fitness
    unit.meta = runit.meta
    unit.network = runit.network
    unit.status += 1
    unit.save()
    print 'pushed'

def stub():
    return HttpResponse('stub')
